home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Camelot / Camelot 043 (1989-06)(Swedish User Group of Amiga)(SE)(PD)[WB].zip / Camelot 043 (1989-06)(Swedish User Group of Amiga)(SE)(PD)[WB].adf / zc / zcc.c < prev    next >
C/C++ Source or Header  |  1989-03-08  |  10KB  |  439 lines

  1. /*  preprocessor for zc (formerly hcc) , a68k assembler, blink
  2. */
  3.  
  4.  
  5. #include <stdio.h>
  6.  
  7. #define toupper( x ) ( x > 'Z' ? x - ('a'-'A'): x )
  8.  
  9. char *malloc();
  10. extern char *getenv();
  11.  
  12.            /* flags if 1 then will allow that operation
  13.         * to be performed on a file           */
  14. short dozc,doa68k,doblink,dodebug,debug;
  15. short blinkxref,startup,standardblinklib;
  16.  
  17. doexec( x,errmsg,file )
  18. char x[],*errmsg,*file;
  19. {
  20. if( debug ){
  21.   printf("%s\n",x);
  22.   return(1);
  23. }
  24. if( ! Execute(x,0L,0L) ){
  25.   printf(errmsg,file);
  26.   quit();
  27. }
  28. return(1);
  29. }
  30.  
  31. char libdir[32];          /* librarys' dir             */
  32. char cmddir[32];         /*  zc,a68k,blink 's dir     */
  33. char xrefname[128];        /* blink xref file output     */
  34. char blinklibs[128];       /* blink lib direc        */
  35. char blinkname[128];      /* output file from a68k     */
  36. char a68kname[128];     /* output file from zc       */
  37. char zcopts[128];    /* zc options for each phase */
  38. char a68kopts[128];    /* a68k options            */
  39. char zctemp[128];     /* CCTEMP dir           */
  40. char blinkopts[128]; /* blink options          */
  41. char buf[256];        /* command line         */
  42. char buf2[256];    /* scratch buf        */
  43.  
  44. /* memory allocation/deallocation routines */
  45. struct mem {
  46. struct mem *prev;
  47. long len;
  48. char *memory;
  49. } *curmem;
  50.  
  51.  
  52. char *jmalloc(n)
  53. long n;
  54. {
  55. char *buf;
  56. struct mem *memlist;
  57. buf=(char *)malloc( n+(long )sizeof(struct mem));
  58. if(!buf){
  59.     printf("cc: outofmemory\n");
  60.     quit();
  61. }
  62. memlist=(struct mem *)buf;
  63. memlist->len=n;
  64. memlist->memory=buf+sizeof(struct mem);
  65. memlist->prev=curmem;
  66. curmem=memlist;
  67. return(memlist->memory);
  68. }
  69.  
  70. quit()
  71. {
  72.  
  73.   jfree();
  74.   exit(0);
  75. }
  76.  
  77. jfree(){
  78. struct mem *nxmem;
  79.  
  80. while(curmem != NULL){
  81.   nxmem=curmem->prev;
  82.   free(curmem);  /* frees all the memory we so graciously gobbled up */
  83.   curmem=nxmem;
  84. }
  85. }/*end of jfree */
  86.  
  87.  
  88.  
  89. /*********************************************************
  90.  
  91.   Handles file list compiles,assembles,links
  92.  
  93. **********************************************************/
  94.  
  95.  
  96. /* lists of source file names, as well as type of operation */
  97.  
  98. struct filenm{
  99.   struct filenm *next;
  100.   struct filenm *prev;
  101.   short ab;     /* abnormal file name */
  102.   short zc;      /* 1 if .c file */
  103.   short a68k;      /* 1 if .s file */
  104.   char *name;
  105. }*files,*curfile;
  106.  
  107.  
  108. #define copystring( x )  (char *)strcpy( jmalloc( (long )len((char *) x )), x )
  109.  
  110.  
  111. /* adds a file to the file list
  112.  *   computes whether an compile and/or assembly will be done
  113.  *   also determines whether this is an abnormal file name.
  114.  *   If so then only a link will be done on the file
  115.  */
  116. struct filenm *addfile(name)
  117. char name[];
  118. {
  119. long l;
  120. struct filenm *newfile;
  121. char *filename;
  122.  
  123. newfile = (struct filenm *)jmalloc(sizeof(struct filenm));
  124. newfile->prev = curfile;
  125. newfile->next = NULL; /* last file so far */
  126. if(curfile)
  127.    curfile->next = newfile;
  128. else
  129.    files = newfile;
  130. curfile = newfile;
  131. filename = (char *) copystring( (char *)name);
  132. curfile->name=filename;    /* contains the new filename */
  133. l=len(filename);
  134.  
  135. curfile->ab=0; /* assume it is normal until proven otherwise */
  136. curfile->zc=0;
  137. curfile->a68k=0;
  138.  
  139. if(filename[l-2] == '.'){
  140.   if(filename[l-1]== 'c'){
  141.      curfile->zc = 1;
  142.      curfile->a68k=1;
  143.   }else if (filename[l-1] == 'a' || filename[l-1] == 's'){
  144.      curfile->a68k=1;
  145.   }else if(filename[l-1] != 'o')
  146.      curfile->ab = 1; /* abnormal file name */
  147. }else
  148.   curfile->ab = 1; /* abnormal file name */
  149. }/* end of addfile */
  150.  
  151.  
  152.  
  153. long len(x)
  154. char x[];
  155. {
  156. long i;
  157.  
  158. for(i=0; x[i] != 0 ; i++);
  159. return(i);
  160. }
  161.  
  162.  
  163.  
  164.  
  165. char *tofiletype(nm,buffer,ext1,ext2)
  166. char nm[],buffer[],ext1[],ext2;
  167. {
  168. long l;
  169.  
  170. strcpy(buffer,nm);
  171. l=len(buffer);
  172. if(l < 2 || ( buffer[l-2] != '.') ){
  173.   strcat(buffer,ext1);
  174.   return(buffer);
  175. }
  176. if(ext2)
  177.   buffer[l-1] = ext2;
  178. else
  179.   buffer[l-2] = '\0'; /* must be executable */
  180. return(buffer);
  181. }/*end of tofiletype */
  182.  
  183. #define toassem( x ) tofiletype( x ,a68kname,".s ",'s')
  184. #define tolink( x ) tofiletype( x ,blinkname,".o ",'o')
  185. #define toexec( x ) tofiletype( x ,blinkname,".lnk ",'\0')
  186.  
  187. doerrors()
  188. {
  189. FILE *err;
  190. int nmerrors;
  191.  
  192.   if( (err=fopen("ram:zc.errors","r"))==NULL)
  193.      return();
  194.   nmerrors=0;
  195.   fscanf(err,"%d",&nmerrors);
  196.   close(err);
  197.   if(nmerrors)
  198.      quit();
  199.   return(); /* no errors thank goodness */
  200. }
  201.  
  202.  
  203. /* this assembles the file */
  204. assemfile(nm,outnm)
  205. char nm[],outnm[];
  206. {
  207.  
  208. strcpy(buf,cmddir);
  209. strcat(buf,"a68k <* >* ");
  210. strcat(buf,a68kopts);
  211. strcat(buf,"-o");
  212. strcat(buf,outnm);
  213. strcat(buf," ");
  214. strcat(buf,nm);
  215. Chk_Abort();
  216. doexec(buf,"cc: assemble error: %s\n",nm);
  217. }/*end of assemfile*/
  218.  
  219. /* compiles and/or assembles the files in the file list */
  220. compilefiles(){
  221. struct filenm *file;
  222. char nm[];
  223.  
  224. file=files;
  225. while(file){
  226.   toassem(file->name);/* use this as the input to a68k
  227.                * unless updated below           */
  228.   if(file->zc && dozc ){
  229.      strcpy(buf,cmddir);
  230.      strcat(buf,"zc >* <* -Eram:zc.errors ");
  231.      strcat(buf,zcopts);
  232.      strcat(buf," ");
  233.      if( (file->a68k && doa68k) || file->ab){
  234.        strcat(buf," -O");
  235.        if(file->a68k && doa68k)
  236.      strcpy(buf2,zctemp);  /* use temp file if doing an assemble */
  237.        else
  238.      buf2[0]='\0';
  239.        strcat(buf2,file->name);
  240.        strcat(buf,toassem(buf2));/* use designated outputfile */
  241.      }
  242.      strcat(buf," ");
  243.      strcat(buf,file->name);
  244.      Chk_Abort();
  245.      doexec(buf,"cc: compile error: %s\n",file->name);/* start compiler */
  246.      doerrors(); /* read error file to see if any errors */
  247.   }   /* compiled okay */
  248.   if(file->a68k && doa68k){
  249.      assemfile(a68kname,tolink(file->name)); /* assemble file */
  250.      if(file->zc){ /* if was a c file remove .s file */
  251.        strcpy(buf,"c:delete >* <* ");
  252.        strcat(buf,a68kname);
  253.        Chk_Abort();
  254.        doexec(buf,"cc: delete error: %s\n",a68kname);
  255.      }
  256.   }
  257.   file=file->next;/* get next file */
  258. }/* done with this file, compile & assemble next */
  259. }/* done with files */
  260.  
  261.  
  262. linkfiles(){
  263. struct filenm *file;
  264. char nm[];
  265.  
  266. if(!doblink || files == NULL ) return();/* don't do anything if not supposed to */
  267. file=files;
  268. strcpy(buf,cmddir);
  269. strcat(buf,"blink <* >* ");
  270. if(startup){
  271.   strcat(buf,libdir);
  272.   strcat(buf,"BothStartup.obj ");
  273. }
  274. while(file){
  275.   strcat(buf,tolink(file->name));/* build linker list */
  276.   file = file->next;
  277.   strcat(buf," ");
  278. }
  279. strcat(buf," TO ");
  280. strcat(buf,toexec(files->name));/* use first file name */
  281. strcat(buf," LIB ");
  282. strcat(buf,blinklibs);
  283. if(standardblinklib){
  284.    strcat(buf,libdir);
  285.    strcat(buf,"amiga.lib ");
  286. }
  287. if(!dodebug)
  288.   strcat(buf," NODEBUG ");
  289. if(blinkxref){
  290.   strcat(buf," XREF ");
  291.   strcat(buf,xrefname);
  292. }
  293. Chk_Abort();
  294. doexec(buf,"cc: linker error:\n",NULL);
  295. printf("cc: executable is %s \n",toexec(files->name));
  296. }/* done linking it */
  297.  
  298.  
  299. help()
  300. {
  301.  
  302.   printf("cc: Version 1.0 Preprocessor for \n%s%s%s%s%s%s%s%s%s%s%s%s%s",
  303.      "   cc: Sozobon-C compiler, \n",
  304.      "   as: a68k C.Gibbs Motorola Compatible Assembler, and\n",
  305.      "   blink:  Software Distillery Linker \n",
  306.      "           looks for lib:amiga.lib and lib:BothStartup.obj \n",
  307.      "   Syntax:\n",
  308.      "           cc [OPTIONS] <files.c> <files.s> <files.o> \n\n",
  309.      "   Options:\n",
  310.      "    -Dxxxx   define xxxx,   -Uxxxx undefine xxxx\n",
  311.      "    -C    data->chip,       -F data->fast\n",
  312.      "    -S  don't use startups, -T don't use amiga.lib\n",
  313.      "    -A    don't assemble,   -c don't link\n",
  314.      "    -Ixxxx  include dir,    -V printout actions only\n",
  315.      "    -lxxxx  use library  lib:xxxx.lib\n");
  316. }
  317.  
  318. main(argc,argv)
  319. int argc;
  320. char *argv[];
  321. {
  322.   int i, l;
  323.   char *s;
  324.  
  325.   printf("cc: \n");
  326.   if(argc < 2 || argv[1][0] == '?'){
  327.      help();
  328.      exit(0);
  329.   }
  330.   startup=standardblinklib=1;/* use BothStartup.obj & amiga.lib */
  331.   blinklibs[0]='\0';       /* blink lib direc           */
  332.   blinkname[0]='\0';      /* output file from a68k     */
  333.   a68kname[0]='\0';      /* output file from zc       */
  334.   zcopts[0]='\0';       /* zc options for each phase */
  335.   a68kopts[0]='\0';    /* a68k options              */
  336.   zctemp[0]='\0';     /* CCTEMP dir                */
  337.   blinkopts[0]='\0'; /* blink options             */
  338.   buf[0]='\0';      /* command line              */
  339.   buf2[0]='\0';    /* scratch buf               */
  340.  
  341.   dodebug=debug=0;
  342.   dozc=doa68k=doblink=1;/* will compile,assem,link unless told otherwise*/
  343.   curmem=NULL;/* haven't grabbed any memory yet*/
  344.   files=NULL;
  345.   curfile=NULL;
  346.   blinkxref=0;
  347.   strcpy(xrefname," ");
  348.  
  349.   if( getenv("CCLIB") ){
  350.       strcpy(libdir," ");
  351.       strcat(libdir,getenv("CCLIB")); /* get libdirector */
  352.   }else
  353.       strcpy(libdir," lib:"); /* default directory */
  354.   if( ! getenv("CCEXEC") )
  355.       strcpy(cmddir,"c:");
  356.   else{
  357.       strcpy(cmddir,getenv("CCEXEC")); /*dir for zc,a68k,blink */
  358.   }
  359.   if( getenv("CCTEMP") ){
  360.      strcpy(zctemp,getenv("CCTEMP"));
  361.   }else{
  362.      printf("cc:Warning, environment variable CCTEMP unset\n   Using ram: \n");
  363.      strcpy(zctemp,"ram:");
  364.   }
  365.   if( ! getenv("INCLUDE")){
  366.      printf("cc: Warning, environment variable INCLUDE unset\n");
  367.   }else{
  368.      strcpy(a68kopts," -I");
  369.      strcat(a68kopts,getenv("INCLUDE") );
  370.   }
  371.   for(i = 1; i < argc; i++){/* parse arguments */
  372.      Chk_Abort();  /* Do options */
  373.      if(argv[i][0] == '+'){
  374.     s = argv[i];
  375.     switch(s[1]){
  376.        default:
  377.           printf("cc: No + switches allowed\n");
  378.           break;
  379.     }
  380.       }else if(argv[i][0] == '-' ){
  381.     s = argv[i];
  382.     switch(s[1]){
  383.        case 'A':
  384.        case 'a':
  385.          doblink = doa68k = 0;
  386.          break;
  387.        case 'C':  /* force data into chip memory */
  388.          strcat(zcopts," -C ");
  389.          break;
  390.        case 'c':
  391.          doblink = 0;
  392.          break;
  393.        case 'd':
  394.        case 'D':
  395.          strcat(zcopts," -D");
  396.          strcat(zcopts,&s[2]);
  397.          break;
  398.        case 'F':
  399.          strcat(zcopts," -F ");
  400.          break;
  401.        case 'i':
  402.        case 'I':
  403.          strcat(zcopts," -I");
  404.          strcat(zcopts,&s[2]);
  405.          break;
  406.        case 'l':
  407.          strcat(blinklibs," -l");
  408.          strcat(blinklibs,&s[2]);
  409.          strcat(blinklibs," ");
  410.          break;
  411.        case 'T':
  412.          standardblinklib=0; /* don't use amiga.lib */
  413.          break;
  414.        case 'S':
  415.          startup = 0;/* don't use BothStartup.obj */
  416.          break;
  417.        case 'u':
  418.        case 'U':
  419.          strcat(zcopts," -U");
  420.          strcat(zcopts,&s[2]);
  421.          break;
  422.        case 'v':
  423.        case 'V':
  424.          debug = 1;
  425.          break;
  426.        default:
  427.          printf("bad option: \"%s\"\n", argv[i]);
  428.          exit(1);
  429.          break;
  430.     }
  431.      }else  /* argument wasn't an option so must be a file  */
  432.     addfile(argv[i]);/* add filename to list of files */
  433.   }/* done with parsing arguments */
  434.   compilefiles(); /* compile all the files */
  435.   linkfiles();   /*  link all the files */
  436.   quit();/* cleanup mess and go home */
  437. }
  438.  
  439.